package com.hjw.httpclient.postdemo;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.springframework.http.HttpStatus;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 模拟发送 application/x-www-form-urlencoded 类型的POST请求
 * @author hjwStrart
 * @time 2022-11-20 12:00
 * @version: 1.0
 */
public class Demo1 {

    /**
     * 小细节：userName这个入参，我给他赋了三次值，结果不是覆盖，而是通过，拼接起来了
     * @throws Exception
     */
    @Test
    public void method() throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
//        String urlStr = "www.baidu.com";  定义urlStr时，不携带 "http://" 会报 Target host is not specified异常
        String urlStr = "http://localhost:8080/form/post";
        // 通过 URIBuilder 方式创建的url，不需要对请求参数进行一次 UrlEncoder 编码，URIBuilder以帮助我们完成了此操作
        URIBuilder builder = new URIBuilder(urlStr);
        builder.addParameter("userName","hjw||123");
        builder.addParameter("userName","hjw||123");
        builder.addParameter("userPwd","admin123");
        HttpPost httpPost = new HttpPost(builder.build().toString());

        // 设置请求头（post请求默认Content-Type就是 "application/x-www-form-urlencoded;charset=utf-8"）
        httpPost.addHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");
        // 设置HttpPost请求参数
        /*
            NameValuePair:
                getName(): 表示表单项的 name 属性
                getValue(): 表示表单项的 value 属性
         */
        List<NameValuePair> list = new ArrayList<>();
        // 通过实现类 BasicNameValuePair 封装请求参数
        list.add(new BasicNameValuePair("userName","parameterValue"));
        UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list, Consts.UTF_8);// 使用HttpClient提供的常量，设置编码格式
        // 在前面的案例中，就提及到 HttpEntity 既可以做为接收响应参数的对象，也可以做为封装请求参数的对象
        httpPost.setEntity(formEntity);
        CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
        try {
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.OK.value()) {
                System.out.println("请求成功");
                HttpEntity entity = httpResponse.getEntity();
                String responseStr = EntityUtils.toString(entity);
                System.out.println(responseStr);
                // 确保 HttpEntity 已被消费
                EntityUtils.consume(entity);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
